package com.example.java_gobang2.game;

import com.example.java_gobang2.mapper.UserMapper;
import com.example.java_gobang2.model.Room;
import com.example.java_gobang2.model.RoomRequest;
import com.example.java_gobang2.model.RoomResponse;
import com.example.java_gobang2.service.AIService;
import com.example.java_gobang2.service.ZhiPuAIService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class RoomManager {
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AIService aiService;
    private ConcurrentHashMap<Integer, Room> rooms = new ConcurrentHashMap<>();
    private ObjectMapper objectMapper = new ObjectMapper();


    public void setRooms(int userId,Room room) {
        rooms.put(userId,room);
    }

    public Room getRoom(int userId) {
        return rooms.get(userId);
    }

    public void remove(int userId) {
        rooms.remove(userId);
    }


    public void putChess(String payload) throws IOException {
        RoomRequest request = objectMapper.readValue(payload, RoomRequest.class);
        Room room = getRoom(request.getUserId());
        WebSocketSession session1 = onlineUserManager.getGameRoom(room.getUser1().getUserId());
        WebSocketSession session2 = onlineUserManager.getGameRoom(room.getUser2().getUserId());
        int chess =request.getUserId() == room.getUser1().getUserId() ? 1 : 2;
        log.info("chess:{}",chess);
        if (!room.setChess(request.getRow(), request.getCol(), chess)) {
            return;
        }
//        room.ToStr();
        RoomResponse response = new RoomResponse();
        response.setWinner(room.checkWinner(chess, request.getRow(), request.getCol()));
        if (response.getWinner() != 0) {
            log.info("win:{}",response.getWinner());
            userMapper.updateWin(response.getWinner());
            userMapper.updateLose(chess == 1 ? room.getUser1().getUserId() : room.getUser2().getUserId());
            userMapper.updateWin(chess == 1 ? room.getUser2().getUserId() : room.getUser1().getUserId());
        }
        response.setUserId(request.getUserId());
        response.setRow(request.getRow());
        response.setCol(request.getCol());
        session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    public void putChessAI(String payload) throws IOException {
        RoomRequest request = objectMapper.readValue(payload, RoomRequest.class);
        Room room = getRoom(request.getUserId());
        WebSocketSession session1 = onlineUserManager.getGameRoom(room.getUser1().getUserId());
//        WebSocketSession session2 = onlineUserManager.getGameRoom(room.getUser2().getUserId());
//        int chess =request.getUserId() == room.getUser1().getUserId() ? 1 : 2;
        int chess = 1;
        log.info("chess:{}", chess);
        if (!room.setChess(request.getRow(), request.getCol(), chess)) {
            return;
        }
        RoomResponse response = new RoomResponse();
        response.setWinner(room.checkWinner(chess, request.getRow(), request.getCol()));
        if (response.getWinner() != 0) {
            log.info("win:{}", response.getWinner());
//            userMapper.updateWin(response.getWinner());
            if (response.getWinner() == room.getUser1().getUserId()) {
                userMapper.updateWin(room.getUser1().getUserId());
            } else {
                userMapper.updateLose(room.getUser1().getUserId());
            }
//            userMapper.updateLose(chess == 1 ? room.getUser1().getUserId() : room.getUser2().getUserId());
//            userMapper.updateWin(chess == 1 ? room.getUser2().getUserId() : room.getUser1().getUserId());
        }
        response.setUserId(request.getUserId());
        response.setRow(request.getRow());
        response.setCol(request.getCol());
        session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        RoomResponse response2 = new RoomResponse();
        log.info("棋盘:{}",room.ToStr());

        String ai = aiService.ai(room.ToStr());
//        aiService.ai2(room.ToStr());
        String[] strings = ai.split(",");
        String row = strings[0].replaceAll("\\s", "");
        String col = strings[1].replaceAll("\\s", "");
        log.info("row:{}",row);
        log.info("col:{}",col);

        boolean b = room.setChess(Integer.parseInt(row), Integer.parseInt(col), 2);
        while (!b) {
            ai = aiService.ai("你是一个五子棋大师,我会发一个棋盘给你,2代表你的棋子,1代表敌人的棋子,0代表还没棋子,你现在要下的棋子是2,你不能和我下在同一个地方,第一行是0,第二行是1,\" +\n" +
                    "                        \"第一列是0,第二列是1,告诉我你要下哪里,用坐标告诉我就行,如0,0 是左上角第一个棋子,你最多思考30s,你刚刚下在"+row+","+col+" 这个地方已经被下过棋子,请重新选择一个编号为0的地方,2代表的是你的棋子,不要进行解释说明,即使输了也没关系,直接输出你要下的棋子坐标\n"+room.ToStr());
            strings = ai.split(",");
            row = strings[0].replaceAll("\\s", "");
            col = strings[1].replaceAll("\\s", "");
            log.info("row:{}",row);
            log.info("col:{}",col);
            b = room.setChess(Integer.parseInt(row), Integer.parseInt(col), 2);
        }
        response2.setWinner(room.checkWinner(2, Integer.parseInt(row), Integer.parseInt(col)));
        if (response.getWinner() != 0) {
            log.info("win:{}", response.getWinner());
//            userMapper.updateWin(response.getWinner());
            if (response.getWinner() == room.getUser1().getUserId()) {
                userMapper.updateWin(room.getUser1().getUserId());
            } else {
                userMapper.updateLose(room.getUser1().getUserId());
            }
        }
            response2.setUserId(room.getUser2().getUserId());
            response2.setRow(Integer.parseInt(row));
            response2.setCol(Integer.parseInt(col));
            log.info("ai落子:{}",response2);
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));

//        session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));

    }

//    public void putChessAI2(String payload) throws IOException {
//        RoomRequest request = objectMapper.readValue(payload, RoomRequest.class);
//        Room room = getRoom(request.getUserId());
//        WebSocketSession session1 = onlineUserManager.getGameRoom(room.getUser1().getUserId());
////        WebSocketSession session2 = onlineUserManager.getGameRoom(room.getUser2().getUserId());
////        int chess =request.getUserId() == room.getUser1().getUserId() ? 1 : 2;
//        int chess = 1;
//        log.info("chess:{}", chess);
//        if (!room.setChess(request.getRow(), request.getCol(), chess)) {
//            return;
//        }
//        RoomResponse response = new RoomResponse();
//        response.setWinner(room.checkWinner(chess, request.getRow(), request.getCol()));
//        if (response.getWinner() != 0) {
//            log.info("win:{}", response.getWinner());
////            userMapper.updateWin(response.getWinner());
//            if (response.getWinner() == room.getUser1().getUserId()) {
//                userMapper.updateWin(room.getUser1().getUserId());
//            } else {
//                userMapper.updateLose(room.getUser1().getUserId());
//            }
////            userMapper.updateLose(chess == 1 ? room.getUser1().getUserId() : room.getUser2().getUserId());
////            userMapper.updateWin(chess == 1 ? room.getUser2().getUserId() : room.getUser1().getUserId());
//        }
//        response.setUserId(request.getUserId());
//        response.setRow(request.getRow());
//        response.setCol(request.getCol());
//        session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//        RoomResponse response2 = new RoomResponse();
//        log.info("棋盘:{}",room.ToStr());
//
//        int[] ai2 = aiService.ai3(room.getChessBoard(),request.getRow(),request.getCol());
//        String ai = aiService.ai(room.ToStr());
////        aiService.ai2(room.ToStr());
//        /*String[] strings = ai.split(",");
//        String row = strings[0].replaceAll("\\s", "");
//        String col = strings[1].replaceAll("\\s", "");
//        log.info("row:{}",row);
//        log.info("col:{}",col);*/
//
//        boolean b = room.setChess(Integer.parseInt(row), Integer.parseInt(col), 2);
//        /*while (!b) {
//            ai = aiService.ai("你刚刚下在"+row+","+col+" 这个地方已经被下过棋子,请重新选择一个编号为0的地方,2代表的是你的棋子,不要进行解释说明,直接输出你要下的棋子坐标\n"+room.ToStr());
//            strings = ai.split(",");
//            row = strings[0].replaceAll("\\s", "");
//            col = strings[1].replaceAll("\\s", "");
//            log.info("row:{}",row);
//            log.info("col:{}",col);
//            b = room.setChess(Integer.parseInt(row), Integer.parseInt(col), 2);
//        }*/
//        response2.setWinner(room.checkWinner(2, Integer.parseInt(row), Integer.parseInt(col)));
//        if (response.getWinner() != 0) {
//            log.info("win:{}", response.getWinner());
////            userMapper.updateWin(response.getWinner());
//            if (response.getWinner() == room.getUser1().getUserId()) {
//                userMapper.updateWin(room.getUser1().getUserId());
//            } else {
//                userMapper.updateLose(room.getUser1().getUserId());
//            }
//        }
//        response2.setUserId(room.getUser2().getUserId());
//        response2.setRow(Integer.parseInt(row));
//        response2.setCol(Integer.parseInt(col));
//        log.info("ai落子:{}",response2);
//        session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
//
////        session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//
//    }
}
